//File   : play.c  
//Author : Loon <sepnic@gmail.com>  
  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include  <stdint.h>
#include "wav_parser.h"  

size_t get_file_size(char *filename)  
{  
    FILE *fp=fopen(filename,"r");  
    if(!fp) return -1;  
    fseek(fp,0L,SEEK_END);  
    size_t size=ftell(fp);  
    fclose(fp);  
      
    return size;  
}  

int SNDWAV_Record(WAVContainer_t *wav, char *filename, char *info_file_name, char magic)  
{  
    int load, ret;  
    size_t written = 0;  
    size_t count = LE_INT(wav->chunk.length);  
    int fmt_bytes;
    size_t info_size;
    char ch,ch_ori,ch_tmp;
    int i;
    int info_fd;
    uint64_t info_file_len = get_file_size(info_file_name);

    info_fd = open(info_file_name, O_RDONLY);  
    if (info_fd < 0) {  
        fprintf(stderr, "Error open [%s]\n", info_file_name);  
        return -1;  
    }  

    FILE *fp=fopen(filename,"r+");  

    if(wav->format.fmt_size % 8 == 0){
	fmt_bytes = wav->format.fmt_size/8;
    }else{
	fmt_bytes = wav->format.fmt_size/8 + 1;
    }

    fseek(fp, sizeof(WAVContainer_t), SEEK_SET);
    printf("sizeof WAVContainer_t is %ld\n", sizeof(WAVContainer_t));
    fseek(fp, fmt_bytes - 1, SEEK_CUR);

    for(i = 0; i < 8; i++){
    	ch = *((char *)&info_file_len + i);
	ch ^= magic;
	fwrite(&ch, 1, 1, fp);	
	fseek(fp, fmt_bytes, SEEK_CUR);
    }

    while(1)
    {
    	if(read(info_fd,&ch,1) == 1){
		//printf("ch is %x\n",ch);
		ch ^= magic;
		printf("after magic ch is %x\n",ch);
		fread(&ch_ori, 1, 1, fp);
		//printf("ch_ori1 is %x\n",ch_ori);

		fseek(fp, -1, SEEK_CUR);
		ch_tmp = (ch_ori & 0xf0)|(ch & 0x0f);
		fwrite(&ch_tmp, 1, 1, fp);
		fseek(fp, fmt_bytes, SEEK_CUR);

		fread(&ch_ori, 1, 1, fp);
		//printf("ch_ori2 is %x\n",ch_ori);
		fseek(fp, -1, SEEK_CUR);
		ch_tmp = (ch_ori & 0xf0)|((ch & 0xf0)>>4);
		fwrite(&ch_tmp, 1, 1, fp);
		fseek(fp, fmt_bytes, SEEK_CUR);
	}else{
	    break;
	}
    }
    fclose(fp);  
    printf("OK\n");
    return 0;
}  

void SNDWAV_Play(WAVContainer_t *wav, char *filename, char *info_file_name, char magic)  
{  
    uint64_t info_file_len;
    int fmt_bytes;
    uint64_t i;
    char ch,ch_tmp1,ch_tmp2;

    FILE *fp=fopen(filename,"r");  
    FILE *info_fp=fopen(info_file_name,"w");  

    if(wav->format.fmt_size % 8 == 0){
	fmt_bytes = wav->format.fmt_size/8;
    }else{
	fmt_bytes = wav->format.fmt_size/8 + 1;
    }

    fseek(fp, sizeof(WAVContainer_t), SEEK_SET);
    printf("sizeof WAVContainer_t is %ld\n", sizeof(WAVContainer_t));
    fseek(fp, fmt_bytes - 1, SEEK_CUR);

    for(i = 0; i < 8; i++){
	fread(&ch, 1, 1, fp);	
	ch ^= magic;
    	*((char *)&info_file_len + i) = ch;
	fseek(fp, fmt_bytes, SEEK_CUR);
    }
    
    printf("file len is %ld\n", info_file_len);
    for(i = 0; i < info_file_len; i++){
	fread(&ch_tmp1, 1, 1, fp);
	fseek(fp, fmt_bytes, SEEK_CUR);
	fread(&ch_tmp2, 1, 1, fp);
	fseek(fp, fmt_bytes, SEEK_CUR);
	ch = (ch_tmp1 & 0x0f) | ((ch_tmp2 & 0x0f)<<4);
	ch ^= magic;
	fwrite(&ch, 1, 1, info_fp);
    }

    fclose(fp);  
    fclose(info_fp);  
}  
  
int main(int argc, char *argv[])  
{  
    char *filename;  
    char *file_info;  
    char *option;  
    char *magic_str;  
    char magic;
    char *devicename = "default";  
    int fd;  
    int fmt_bytes;
    size_t info_file_len;

    WAVContainer_t wav;  
      
    if (argc != 5) {  
        fprintf(stderr, "Usage: ./play <FILENAME> <FILENAME> <option>\n");  
        return -1;  
    }  
      
    filename = argv[1];  
    file_info = argv[2]; 
    option = argv[3]; 
    magic_str = argv[4]; 
    
    fd = open(filename, O_RDWR);  
    if (fd < 0) {  
        fprintf(stderr, "Error open [%s]\n", filename);  
        return -1;  
    }  

    if (WAV_ReadHeader(fd, &wav) < 0) {  
        fprintf(stderr, "Error WAV_Parse [%s]\n", filename);  
        goto Err;  
    }  
    close(fd);  

    if(wav.format.fmt_size % 8 == 0){
	fmt_bytes = wav.format.sample_length/8;
    }else{
	fmt_bytes = wav.format.sample_length/8 + 1;
    }

    printf("fmt_bytes is %d\n", fmt_bytes);
    printf("file_size is %ld\n",info_file_len);
    printf("sizeof size_t is %ld\n",sizeof(size_t));
    
    magic = atoi(magic_str);
    printf("magic is %d\n", magic);

    if(strcmp(option, "in") == 0){
	    info_file_len = get_file_size(file_info);
	    if (info_file_len > LE_INT(wav.chunk.length)/fmt_bytes){
		printf("file_info is too long\n");
		exit(-1);
	    }

	    SNDWAV_Record(&wav, filename, file_info, magic);  
    }else if(strcmp(option, "out") == 0){
	    SNDWAV_Play(&wav, filename, file_info, magic);  
    }else{
	    printf("option err\n");
	    exit(-1);
    }
  
    return 0;  
  
Err:  
    close(fd);  
    return -1;  
}  
